package com.starrin.trashtalk.dao;

import com.starrin.trashtalk.PersistenceListener;
import com.starrin.trashtalk.SetDTO;
import com.starrin.trashtalk.model.Player;
import com.starrin.trashtalk.model.SingleMatch;
import com.starrin.trashtalk.model.SingleSet;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.Date;
import java.util.List;


/**
 * Created by larsstarrin on 31/08/14.
 */
public class MatchDAOImpl implements MatchDAO {

    private PlayerDAO playerDAO = new PlayerDAOImpl();

    @Override
    public boolean registerMatchResult(Date matchDate, Long homePlayerId, Long awayPlayerId, SetDTO setDTO1, SetDTO setDTO2, SetDTO setDTO3) {
        //Save match to database
        EntityManager em = PersistenceListener.createEntityManager();
        em.getTransaction().begin();

        Player homePlayer = playerDAO.findById(homePlayerId);
        Player awayPlayer = playerDAO.findById(awayPlayerId);

        SingleMatch match = new SingleMatch();
        match.setPlayer1(homePlayer);
        match.setPlayer2(awayPlayer);
        match.setDate(matchDate);

        SingleSet set1 = new SingleSet();
        SingleSet set2 = new SingleSet();
        SingleSet set3 = new SingleSet();

        //Calculate winner
        int setsPlayer1 = 0;
        int setsPlayer2 = 0;

        set1.setGamesPlayer1(setDTO1.getGamesPlayer1());
        set1.setGamesPlayer2(setDTO1.getGamesPlayer2());
        if(setDTO1.getGamesPlayer1() > 0 || setDTO1.getGamesPlayer2() > 0) {
            if(setDTO1.getGamesPlayer1() > setDTO1.getGamesPlayer2() && setDTO1.getGamesPlayer1() == 6) {
                set1.setSetWinner(homePlayer);
                setsPlayer1 ++;
            } else if(setDTO1.getGamesPlayer2() > setDTO1.getGamesPlayer1() && setDTO1.getGamesPlayer2() == 6){
                set1.setSetWinner(awayPlayer);
                setsPlayer2++;
            }
            match.addSet(set1);
        }
        set2.setGamesPlayer1(setDTO2.getGamesPlayer1());
        set2.setGamesPlayer2(setDTO2.getGamesPlayer2());
        if(setDTO2.getGamesPlayer1() > 0 || setDTO2.getGamesPlayer2() > 0) {
            if(setDTO2.getGamesPlayer1() > setDTO2.getGamesPlayer2() && setDTO2.getGamesPlayer1() == 6) {
                set2.setSetWinner(homePlayer);
                setsPlayer1 ++;

            } else if(setDTO2.getGamesPlayer2() > setDTO2.getGamesPlayer1() && setDTO2.getGamesPlayer2() == 6){
                set2.setSetWinner(awayPlayer);
                setsPlayer2 ++;
            }
            match.addSet(set2);
        }

        set3.setGamesPlayer1(setDTO3.getGamesPlayer1());
        set3.setGamesPlayer2(setDTO3.getGamesPlayer2());
        if(setDTO3.getGamesPlayer1() > 0  || setDTO3.getGamesPlayer2() > 0) {
            if(setDTO3.getGamesPlayer1() > setDTO3.getGamesPlayer2() && setDTO3.getGamesPlayer1() == 6) {
                set3.setSetWinner(homePlayer);
                setsPlayer1 ++;
            } else if(setDTO3.getGamesPlayer2() > setDTO3.getGamesPlayer1() && setDTO3.getGamesPlayer2() == 6){
                set3.setSetWinner(awayPlayer);
                setsPlayer2 ++;
            }
            match.addSet(set3);
        }

        if(setsPlayer1 > setsPlayer2) {
             match.setWinner(homePlayer);
        }  else if(setsPlayer2 > setsPlayer1) {
            match.setWinner(awayPlayer);
        }

        em.persist(match);
        em.getTransaction().commit();
        em.close();
        return true;
    }

    @Override
    public List<SingleMatch> findAllMatches() {
        EntityManager em = PersistenceListener.createEntityManager();
        Query query = em.createQuery("select distinct m from SingleMatch m left join fetch m.singleSets order by m.date desc");
        List<SingleMatch> list = query.getResultList();
        em.close();
        return list;
    }

    @Override
    public List<SingleMatch> findMatchesBetween(Long player1Id, Long player2Id) {
        EntityManager em = PersistenceListener.createEntityManager();
        Query query = em.createQuery("from SingleMatch m join fetch m.singleSets " +
                "where (m.player1.id = :player1Id or m.player1.id = :player2Id) and (m.player2.id = :player1Id or m.player2.id = :player2Id)" +
                "order by m.date desc");
        query.setParameter("player1Id", player1Id);
        query.setParameter("player2Id", player2Id);
        List<SingleMatch> list = query.getResultList();
        em.close();
        return list;
    }
}
